home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $VER: vectorop.c 3.00D (11.8.97)
- **
- ** STScan vectorization routines
- **
- ** Written by Frank-Christian Kruegel, Henning Peters, Andreas R. Kleinert
- ** GNU General Public License V2
- */
-
- #include "stscan.h"
-
- #define REGION_SIZE 64
- #define CHAINLEN 16384
-
- static UWORD __far chpixels[2][CHAINLEN];
- static UWORD __far lnpixels[2][CHAINLEN];
- static UWORD __far regio_x[128][128];
- static UWORD __far regio_y[128][128];
- static UBYTE __far regio_done[128][128];
- static UBYTE __far regio_numx,regio_numy;
- static char str_filenam[256]="";
- static UWORD maxdiff=4;
-
- static UBYTE getpixel(UWORD x,UWORD y)
- {
- UBYTE res;
-
- res = (UBYTE) (*(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&bitval[x&7])?0:1;
-
- return(res);
- }
-
- static void clrpixel(UWORD x,UWORD y)
- { *(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))|=bitval[x&7];
- }
-
- static void setpixel(UWORD x,UWORD y)
- { *(memptr+(ULONG)y*(ULONG)membpl+(ULONG)(x>>3))&=invbitval[x&7];
- }
-
- static UBYTE subiter(UWORD nx,UWORD ny)
- { UWORD x,y;
- UBYTE f,vw,vnw,vn,vne,ve,vse,vs,vsw;
-
- f=0;
- for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
- { for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
- { if ((getpixel(x,y))&&((x&1)==(y&1)))
- { vw= getpixel(x-1,y);
- vnw=getpixel(x-1,y-1);
- vn= getpixel(x ,y-1);
- vne=getpixel(x+1,y-1);
- ve= getpixel(x+1,y);
- vse=getpixel(x+1,y+1);
- vs= getpixel(x ,y+1);
- vsw=getpixel(x-1,y+1);
- if ( (( ((vw^1)&(vnw|vn))
- +((vn^1)&(vne|ve))
- +((ve^1)&(vse|vs))
- +((vs^1)&(vsw|vw)) )==1)
- || ((!(vw))&&(!(vnw))&&(!(vn))&&(!(vne))&&
- (!(ve))&&(!(vse))&&(!(vs))&&(!(vsw)) ) )
- { clrpixel(x,y);
- if (!(f)) f=((vnw|vse)&(vne|vsw)&(vn|vs)&(vw|ve));
- }
- }
- }
- }
- for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
- { for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
- { if ((getpixel(x,y))&&((x&1)!=(y&1)))
- { vw= getpixel(x-1,y);
- vnw=getpixel(x-1,y-1);
- vn= getpixel(x ,y-1);
- vne=getpixel(x+1,y-1);
- ve= getpixel(x+1,y);
- vse=getpixel(x+1,y+1);
- vs= getpixel(x ,y+1);
- vsw=getpixel(x-1,y+1);
- if ( (( ((vw^1)&(vnw|vn))
- +((vn^1)&(vne|ve))
- +((ve^1)&(vse|vs))
- +((vs^1)&(vsw|vw)) )==1)
- || ((!(vw))&&(!(vnw))&&(!(vn))&&(!(vne))&&
- (!(ve))&&(!(vse))&&(!(vs))&&(!(vsw)) ) )
- { clrpixel(x,y);
- if (!(f)) f=((vnw|vse)&(vne|vsw)&(vn|vs)&(vw|ve));
- }
- }
- }
- }
- return(f);
- }
-
- static UBYTE chkblack(UWORD nx,UWORD ny)
- { UWORD x,y;
- UBYTE f=1;
- for (y=regio_y[nx][ny];y<regio_y[nx][ny+1];y++)
- { for (x=regio_x[nx][ny];x<regio_x[nx+1][ny];x++)
- if (!(getpixel(x,y)))
- { f=0;
- y=regio_y[nx][ny+1];
- x=regio_x[nx+1][ny];
- }
- }
- return(f);
- }
-
- static void straighten(void)
- { UWORD x,y;
- UBYTE vnw,vne,vse,vsw;
-
- for (y=1;y<memheight-1;y++)
- { for (x=1;x<memwidth-1;x++)
- { if ((getpixel(x,y))
- &&(!(getpixel(x-1,y)))&&(!(getpixel(x+1,y)))
- &&(!(getpixel(x,y-1)))&&(!(getpixel(x,y+1))))
- { vnw=getpixel(x-1,y-1);
- vne=getpixel(x+1,y-1);
- vse=getpixel(x+1,y+1);
- vsw=getpixel(x-1,y+1);
- if (((vnw))&&(!(vne))&&(!(vse))&&((vsw)))
- { clrpixel(x,y);
- setpixel(x-1,y);
- }
- else if ((!(vnw))&&((vne))&&((vse))&&(!(vsw)))
- { clrpixel(x,y);
- setpixel(x+1,y);
- }
- else if (((vnw))&&((vne))&&(!(vse))&&(!(vsw)))
- { clrpixel(x,y);
- setpixel(x,y-1);
- }
- else if ((!(vnw))&&(!(vne))&&((vse))&&((vsw)))
- { clrpixel(x,y);
- setpixel(x,y+1);
- }
- }
- }
- }
- }
-
- void thin(void)
- { UWORD x,y,i;
- ULONG pgofs1,pgofs2;
- char wtitel[96];
- UBYTE p,f,ende;
-
-
- membpl=(memwidth>>3);
- pgofs1=(memwidth>>3)*(memheight-1);
- for (i=0;i<(memwidth>>3);i++)
- { *(memptr+i)=255;
- *(memptr+pgofs1+i)=255;
- }
- pgofs1=0;
- pgofs2=membpl-1;
- for (i=0;i<memheight;i++)
- { *(memptr+pgofs1)|=128;
- *(memptr+pgofs2)|=1;
- pgofs1+=membpl;
- pgofs2+=membpl;
- }
- p=1;
- regio_numx=memwidth/REGION_SIZE;
- regio_numy=memheight/REGION_SIZE;
- regio_x[0][0]=1;
- regio_x[1][0]=REGION_SIZE+(memwidth%REGION_SIZE)/2;
- for (x=2;x<regio_numx;x++) regio_x[x][0]=REGION_SIZE+regio_x[x-1][0];
- regio_x[regio_numx][0]=memwidth-1;
- for (x=0;x<regio_numx;x++) regio_y[x][0]=1;
- for (x=0;x<=regio_numx;x++)
- { regio_y[x][1]=REGION_SIZE+(memheight%REGION_SIZE)/2;
- regio_x[x][1]=regio_x[x][0];
- }
- for (y=2;y<regio_numy;y++) for (x=0;x<=regio_numx;x++)
- { regio_y[x][y]=REGION_SIZE+regio_y[x][y-1];
- regio_x[x][y]=regio_x[x][0];
- }
- for (x=0;x<regio_numx;x++) regio_y[x][regio_numy]=memheight-1;
- for (y=0;y<regio_numy;y++) for (x=0;x<regio_numx;x++) regio_done[x][y]=1;
- do
- { ende=0;
- for (y=0;y<regio_numy;y++) for (x=0;x<regio_numx;x++)
- { if (regio_done[x][y])
- { if (subiter(x,y)) f=regio_done[x][y]=1;
- else if (chkblack(x,y)) f=regio_done[x][y]=1;
- else f=regio_done[x][y]=0;
- ende|=f;
- sprintf(&wtitel[0],"Region (%02d;%02d) Pass %02d",x,y,p);
- SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
- }
- }
- p++;
- } while (ende);
- SetWindowTitles(win,"Cleanup",(UBYTE *)-1);
- straighten();
- SetWindowTitles(win," ",(UBYTE *)-1);
- }
-
- static UWORD getchain(UWORD x, UWORD y)
- { UWORD lx,ly,pos;
- UBYTE f=1;
-
- lx=x;
- ly=y;
- pos=0;
- while ((f)&&(pos<CHAINLEN))
- { chpixels[0][pos]=lx;
- chpixels[1][pos]=ly;
- clrpixel(lx,ly);
- pos++;
- if (getpixel(lx-1,ly )) lx--;
- else if (getpixel(lx-1,ly-1)) {lx--; ly--;}
- else if (getpixel(lx ,ly-1)) ly--;
- else if (getpixel(lx+1,ly-1)) {lx++; ly--;}
- else if (getpixel(lx+1,ly )) lx++;
- else if (getpixel(lx+1,ly+1)) {lx++; ly++;}
- else if (getpixel(lx ,ly+1)) ly++;
- else if (getpixel(lx-1,ly+1)) {lx--; ly++;}
- else f=0;
- }
- return(pos);
- }
-
- static UWORD getline(UWORD x0, UWORD y0, UWORD x1, UWORD y1)
- { WORD xdiff,ydiff,xstep,ystep, sum;
- UWORD i;
- WORD step[2]={-1,1};
-
- xstep=step[(x0<x1)]; ystep=step[(y0<y1)];
- xdiff=abs(x0-x1); ydiff=abs(y0-y1);
-
- lnpixels[0][0]=x0;
- lnpixels[1][0]=y0;
- i=1;
- if (xdiff>ydiff)
- { sum=xdiff/2;
- while (x0!=x1)
- { x0+=xstep;
- sum-=ydiff;
- if (sum<0)
- { y0+=ystep;
- sum+=xdiff;
- }
- lnpixels[0][i]=x0;
- lnpixels[1][i]=y0;
- i++;
- }
- }
- else
- { sum=ydiff/2;
- while (y0!=y1)
- { y0+=ystep;
- sum-=xdiff;
- if (sum<0)
- { x0+=xstep;
- sum+=ydiff;
- }
- lnpixels[0][i]=x0;
- lnpixels[1][i]=y0;
- i++;
- }
- }
- return(i);
- }
-
- static void polygon(UWORD startpos,UWORD len,FILE *vecfile)
- { UWORD sx0,sy0,sx1,sy1,m,n,s,lnlen,cbdist,mcbdist,mdpos;
-
- sx0=chpixels[0][startpos];
- sy0=chpixels[1][startpos];
- sx1=chpixels[0][startpos+len-1];
- sy1=chpixels[1][startpos+len-1];
- lnlen=getline(sx0,sy0,sx1,sy1);
- mdpos=0;
- mcbdist=0;
- s=len/lnlen;
- if (s<1) s=1;
- for(m=0,n=startpos;m<lnlen;m++,n+=s)
- { cbdist=abs(chpixels[0][n]-lnpixels[0][m])
- +abs(chpixels[1][n]-lnpixels[1][m]);
- if (cbdist>mcbdist)
- { mdpos=m;
- mcbdist=cbdist;
- }
- }
- if (mcbdist>maxdiff)
- { polygon(startpos,mdpos,vecfile);
- polygon(startpos+mdpos,len-mdpos,vecfile);
- }
- else
- { fprintf(vecfile,"%d %d\n",sx0,memheight-sy0);
- fprintf(vecfile,"%d %d\n\n",sx1,memheight-sy1);
- }
- }
-
- void vectorize(void)
- { UWORD p,x,y,len;
- FILE *vecfile;
- char wtitel[96];
-
- if (filerequest("Speichern Vektor TXT File",str_filenam))
- { p=0;
- membpl=(memwidth>>3);
- vecfile=fopen(str_filenam,"w");
- for (y=1;y<memheight-1;y++)
- { for (x=1;x<memwidth-1;x++)
- { if (getpixel(x,y))
- { len=getchain(x,y);
- polygon(0,len,vecfile);
- sprintf(&wtitel[0],"Chain %04d",++p);
- SetWindowTitles(win,&wtitel[0],(UBYTE *)-1);
- }
- }
- }
- fclose(vecfile);
- SetWindowTitles(win," ",(UBYTE *)-1);
- }
- }
-
- void chngmaxdiff(void)
- {
- ULONG longnum;
-
- longnum = maxdiff;
-
- if(rtGetLong(&longnum, "Enter vectorization accuracy", NULL,
- RTGL_ShowDefault, TRUE,
- RTGL_Min, 2,
- RTGL_Max, 100,
- TAG_END)) maxdiff=longnum;
- }
-